// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#include <pollux/python/file/PyFile.h>
#include <fmt/format.h>
#include <melon/string.h>
#include <pollux/dwio/common/reader_factory.h>

namespace kumo::pollux::py {
namespace {

dwio::common::FileFormat toFileFormat(std::string formatString) {
  melon::toLowerAscii(formatString);
  auto format = dwio::common::toFileFormat(formatString);

  if (format == dwio::common::FileFormat::UNKNOWN) {
    throw std::runtime_error(
        fmt::format("Unknown file format: {}", formatString));
  }
  return format;
}

} // namespace

PyFile::PyFile(std::string filePath, std::string formatString)
    : filePath_(std::move(filePath)),
      fileFormat_(toFileFormat(std::move(formatString))) {}

std::string PyFile::toString() const {
  return fmt::format("{} ({})", filePath_, fileFormat_);
}

PyType PyFile::getSchema() {
  // If the schema was read yet, we will need to open the file and read its
  // metadata.
  if (fileSchema_ == nullptr) {
    // Create ephemeral memory pool to open and read metadata from the file.
    auto rootPool = memory::memoryManager()->addRootPool();
    auto leafPool = rootPool->addLeafChild("py_get_file_schema");

    auto readFile = filesystems::getFileSystem(filePath_, nullptr)
                        ->openFileForRead(filePath_);
    auto input = std::make_unique<dwio::common::BufferedInput>(
        std::shared_ptr<ReadFile>(std::move(readFile)), *leafPool);
    auto reader =
        dwio::common::getReaderFactory(fileFormat_)
            ->createReader(
                std::move(input), dwio::common::ReaderOptions{leafPool.get()});
    fileSchema_ = reader->rowType();
  }
  return PyType{fileSchema_};
}

} // namespace kumo::pollux::py
